//
//  LazyLoad.swift
//  CooperSwift_Example
//
//  Created by 计海峰 on 2021/11/30.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import Foundation
import UIKit

public typealias RunloopBlock = ((IndexPath) -> Bool)

private struct AssociateKeys {
    static var tasksArr: Void?
    static var tasksIndexPathArr: Void?
    static var maxQueueLength: Void?
}

public protocol LazyLoadProtocol: AssociatedObjectStore { }

public extension LazyLoadProtocol {
        
    /// 任务block列表
    var tasksArr: [RunloopBlock] {
        get {
            return associatedObject(forKey: &AssociateKeys.tasksArr, default: [], ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            objc_setAssociatedObject(self, &AssociateKeys.tasksArr, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    /// 任务的列表
    var tasksIndexPathArr: [IndexPath] {
        get {
            return associatedObject(forKey: &AssociateKeys.tasksIndexPathArr, default: [], ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            objc_setAssociatedObject(self, &AssociateKeys.tasksIndexPathArr, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
   /// 最大任务 10
    var maxQueueLength: Int {
        get {
            return associatedObject(forKey: &AssociateKeys.maxQueueLength, default: 10, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            objc_setAssociatedObject(self, &AssociateKeys.maxQueueLength, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    /// 添加runloop的监听
    fileprivate func addRunloopObserver() {
         //获取当前RunLoop
         let runLoop: CFRunLoop = CFRunLoopGetCurrent()
         //定义一个上下文
         var context: CFRunLoopObserverContext = CFRunLoopObserverContext(version: 0, info: unsafeBitCast(self, to: UnsafeMutableRawPointer.self), retain: nil, release: nil, copyDescription: nil)
         //定义一个观察者
         if let observer = CFRunLoopObserverCreate(kCFAllocatorDefault, CFRunLoopActivity.beforeWaiting.rawValue, true, 0, self.observerCallbackFunc(), &context){
             //添加当前RunLoop的观察者
             CFRunLoopAddObserver(runLoop, observer, .commonModes);
         }
     }
        
    /// 回调函数
    func observerCallbackFunc() -> CFRunLoopObserverCallBack {
        return {(observer, activity, context) -> Void in
            if context == nil {//如果没有取到  直接返回
                return
            }
            // 崩溃的与原因不在这里  isFromADGuide 的问题 不应该取反
            // 取出上下文 就是当前的vc
            let target = unsafeBitCast(context, to: NSObject.self)
            guard let vc = target as? LazyLoadProtocol else { return }
            if vc.tasksArr.count == 0 {
                return
            }
            //取出任务
            if let unit = vc.tasksArr.first, let indexP = vc.tasksIndexPathArr.first {
                var result = false
                while (result == false && !vc.tasksArr.isEmpty && !vc.tasksIndexPathArr.isEmpty){
                    //执行任务
                    result = unit(indexP);
                    //干掉第一个任务
                    _ = vc.tasksArr.remove(at: 0)
                    _ = vc.tasksIndexPathArr.remove(at: 0)
                }
            }
        }
    }
    
    /// 添加新的任务的方法!
     func addTask(_ indexP: IndexPath, unit: @escaping RunloopBlock) {
         self.tasksArr.append(unit)
         self.tasksIndexPathArr.append(indexP)
         // 判断一下 保证没有来得及显示的cell不会绘制
         if self.tasksArr.count > self.maxQueueLength {
             _ = self.tasksArr.remove(at: 0)
             _ = self.tasksIndexPathArr.remove(at: 0)
         }
     }
    
//    ///
//    func noSleep() {
//
//    }
    
    func startObserve() {
        addRunloopObserver()
    }
    
}

//private class Holder: NSObject {
//
//    func noSleep() {
//        //创建定时器 (保证runloop回调函数一直在执行)
//        let displayLink = CADisplayLink(target: self, selector: #selector(notDoSomething))
//        displayLink.add(to: .current, forMode: .common)
//    }
//
//    @objc func notDoSomething() {
//
//    }
//
//}
